package corpus;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import parser.ParserAnnotation;
import parser.ParserPipeline;

public class SentPolarityCorpus {
	private TreeMap<String, TreeMap<String, String>> corpus;
	private TreeMap<String, ParserAnnotation> parsedCorpus;

	public SentPolarityCorpus(String dirpath) throws IOException {
		corpus = new TreeMap<String, TreeMap<String, String>>();
		File dir = new File(dirpath);
		if (dir.isDirectory()) {
			for (File in : dir.listFiles()) {
				if (in.getAbsolutePath().contains("test.txt"))
					continue;
				add(in);
			}
		} else {
			add(dir);
		}
		parsedCorpus = new TreeMap<String, ParserAnnotation>();
	}

	public ParserAnnotation getParsedPA(String sentence, ParserPipeline pp) {
		if (parsedCorpus.containsKey(sentence)) {
			System.out.println("cache");
			return parsedCorpus.get(sentence);
		} else {
			ParserAnnotation pa = pp.make(sentence);
			pa.setSkipSentDetection(true);
			pa.parse();
			return pa;
		}
	}

	public TreeSet<String> getSentences(String polarity) {
		TreeSet<String> sentences = new TreeSet<String>();
		for (TreeMap<String, String> corp : corpus.values())
			for (Entry<String, String> e : corp.entrySet())
				if (e.getValue().equals(polarity))
					sentences.add(e.getKey());
		return sentences;
	}

	public int getLongestSentence() {
		int max = 1;
		for (String s : getCorpus().keySet()) {
			int value = s.split(" ").length;
			if (value > max)
				max = value;
		}
		return max;
	}

	public Map<String, String> getCorpus() {
		TreeMap<String, String> merged = new TreeMap<String, String>();
		for (TreeMap<String, String> map : corpus.values())
			merged.putAll(map);
		return merged;
	}

	public Set<String> getCorpusNames() {
		return corpus.keySet();
	}

	public String getDomain() {
		if (corpus.size() != 1)
			throw new Error("There are many domains.");
		return corpus.firstKey();
	}

	public Map<String, String> getCorpus(String domain) {
		return corpus.get(domain);
	}

	private void add(File in) throws IOException {
		TreeMap<String, String> corp = new TreeMap<String, String>();
		BufferedReader br = new BufferedReader(new FileReader(in));
		while (br != null) {
			String line = br.readLine();
			if (line == null)
				break;
			if (line.isEmpty())
				continue;
			Scanner scr = new Scanner(line);
			String rating = scr.next();
			if (!scr.hasNextLine() && !rating.equals("neu|pos|neg"))
				continue;
			String sent = scr.nextLine().substring(1);
			if (!rating.matches("neu|pos|neg"))
				throw new CorpusFormatException("Unknown rating " + rating
						+ " in " + in.getCanonicalPath());
			corp.put(sent, rating);
		}
		corpus.put(in.getName().replace(".txt", ""), corp);
	}

	public void remove(SentPolarityCorpus newSet) {
		for (Map<String, String> m : corpus.values()) {
			for (String sent : newSet.getCorpus().keySet())
				m.remove(sent);
		}
	}

	public void output(Writer w) throws IOException {
		for (TreeMap<String, String> corp : corpus.values())
			for (Entry<String, String> e : corp.entrySet())
				w.append(e.getValue() + "\t" + e.getKey() + "\n");
		w.flush();
		w.close();
	}
}
